Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Blocked users extension #37

Draft
wants to merge 4 commits into
base: master
Choose a base branch
from

Conversation

Smjert
Copy link
Contributor

@Smjert Smjert commented Sep 30, 2018

WORK IN PROGRESS

A simple extension to allow locking and unlocking of linux local user accounts.
Uses "usermod --lock --expiredate 1 " and "usermod --unlock --expiredate '' " to lock and unlock them.
Users can be specified through their username or uid.

Example usage:

// Add a test user
adduser test

// In osqueryi, lock the user
INSERT INTO blocked_users (username) VALUES("test");
or 
INSERT INTO blocked_users (uid) VALUES("<uid>");

// List locked users
SELECT * FROM blocked_users;

// Unlock test user
DELETE FROM blocked_users WHERE username="test";
or
DELETE FROM blocked_users WHERE uid="<uid>";

@mike-myers-tob
Copy link
Contributor

Interesting; I assume the use case is in incident management, to contain the impact of a compromised endpoint.

Some questions:

  • Does usermod --lock immediately log out the user if they are currently logged in?
  • Does it disable all methods of authenticating (e.g., ssh public key) or just password authentication? I have read contradictory information on this.
  • Can the user be left with a message of some kind to explain why they are locked out?
  • Would something similar be possible on macOS, with dscl maybe?

This would be a powerful capability, so we'd want to test to make sure it is safe and always reversible with osquery.

@Smjert
Copy link
Contributor Author

Smjert commented Oct 3, 2018

Interesting; I assume the use case is in incident management, to contain the impact of a compromised endpoint.

That was the intention yes :).

Some questions:

  • Does usermod --lock immediately log out the user if they are currently logged in?

usermod doesn't, as discussed on Slack a kill of all the user processes is needed.

  • Does it disable all methods of authenticating (e.g., ssh public key) or just password authentication? I have read contradictory information on this.

usermod --lock alone will only block the password login. It works by prepending the encrypted password in the shadow file with '!' character, which can never appear in an encrypted password.
Adding --expiredate 1 expires the account, which also blocks ssh logins.

  • Can the user be left with a message of some kind to explain why they are locked out?

The system to lock the user out is pretty raw and basic, so I don't think so.
Maybe with PAM something can be done, but this will probably mean requiring a custom module/config.

  • Would something similar be possible on macOS, with dscl maybe?

Unfortunately don't have a Mac to test this ^^'.

@mike-myers-tob
Copy link
Contributor

mike-myers-tob commented Oct 4, 2018

  • Does usermod --lock immediately log out the user if they are currently logged in?

usermod doesn't, as discussed on Slack a kill of all the user processes is needed.

I think to complete the feature in this PR, that we ought to also support the ability to immediately logout the user.

Perhaps you could kill the user's session (via its parent process) rather than kill each individual process of the user? If I was using a CLI and I were in the sudoers group, I could logout the user named "bob" with $ sudo pkill -KILL -u bob (pkill is wrapping the kill system call (called through libc, as we would too)).

Adding --expiredate 1 expires the account, which also blocks ssh logins.

👍 Blocking SSH logins this way (expiring the account) sounds good to me. Also, it seems that this is the only way to ensure that the account is locked out for all configurations of PAM.

  • Can the user be left with a message of some kind to explain why they are locked out?

The system to lock the user out is pretty raw and basic, so I don't think so.
Maybe with PAM something can be done, but this will probably mean requiring a custom module/config.

Ok, disregard my suggestion.

  • Would something similar be possible on macOS, with dscl maybe?

Unfortunately don't have a Mac to test this ^^'.

@alessandrogario said he could look into that later after this PR is merged. 😁

@Smjert
Copy link
Contributor Author

Smjert commented Oct 7, 2018

I think to complete the feature in this PR, that we ought to also support the ability to immediately logout the user.

That was my thought too :).
I also have a raw list of other things to do like:

  1. Make the code thread safe
  2. Cleanup error logic and input checking
  3. Do not accept root user in the queries, as suggested by @alessandrogario
  4. Add a readonly column to inform about which kind of lock the account has (maybe only the password got locked, manually/externally)

Perhaps you could kill the user's session (via its parent process) rather than kill each individual process of the user? If I was using a CLI and I were in the sudoers group, I could logout the user named "bob" with $ sudo pkill -KILL -u bob (pkill is wrapping the kill system call (called through libc, as we would too)).

So i tried a bit more with a graphical installation (Ubuntu 18.04) by killing the /var/lib/systemd --user process which is owned by the user I want to logout, but it has nasty side effects which are to also logout the current user.. and apparently break its log in.

No idea why it does that, but I've found a way which works cleanly, using loginctl, which is a tool from systemd to manage sessions.
It uses sdbus internally, so I can try to dlopen the relevant libraries (to avoid and do the same call loginctl does to terminate the session (which seems pretty straightforward).
Then if this doesn't terminate the user processes, resort to a fallback method, which kills processes individually using libproc.

Beyond having no dependencies with dlopen, I think I could also check for the presence of the systemd libraries, if there's some distro that has to be supported that doesn't have them; in that case I could use the fallback method only.

- Add ShadowEntry and PasswdEntry which represent a parsed line in the
respective files

- Add ShadowFile to read the shadow file and hold all the ShadowEntry
instances

- The functions to access the shadow file and passwd file are now thread
safe

- insert and delete acquire a write lock, select acquires a read lock.
This is to reduce the possibility of corrupting the files while
modifying them
@mike-myers-tob mike-myers-tob marked this pull request as draft November 9, 2020 18:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants